/**
 * 根据类名查找元素，解决兼容问题
 * @param className 待查找的类名
 * @param context 查找上下文，可选参数，默认为 document
 * @return 返回根据类名查找到的元素集合
 */
function byClass(className, context) {
	// 如果 context 未传递，则默认为 document
	context = context || document;
	// 浏览器支持使用 context.getElementsByClassName() 方法
	if (context.getElementsByClassName) 
		return context.getElementsByClassName(className);

	/* 浏览器不支持使用 context.getElementsByClassName() 方法 */
	// 保存所有查找到的元素
	var result = []; 
	// 查找所有元素
	var elements = context.getElementsByTagName("*");
	// 遍历每个元素
	for (var i = 0, len = elements.length; i < len; i++) {
		// 当前遍历到元素的所有类名
		var classNames = elements[i].className.split(" ");
		// 遍历当前元素的所有类名
		for (var j = 0, l = classNames.length; j < l; j++) {
			// 待查找类名与当前遍历到的某个类名相同，则说明当前DOM元素是需要被查找出来的元素
			if (classNames[j] === className) {
				result.push(elements[i]);
				break;
			}
		}
	}

	// 返回查找到的元素所在的数组
	return result;
}

/**
 * 根据元素的 id、类名或标签名查找元素
 * @param selector 选择器，#id、.className、element
 * @param context 查询上下文，默认为 document
 * @return 返回根据选择器在查询上下文中查找到的结果
 */
function $(selector, context) {
	// 默认在 document 后代查找
	context = context || document;
	// 判断
	if (selector.indexOf("#") === 0) // id
		return document.getElementById(selector.slice(1));
	if (selector.indexOf(".") === 0) // className
		return byClass(selector.slice(1), context);
	// element
	return context.getElementsByTagName(selector);
}

/**
 * 获取指定元素的CSS属性值
 * @param element DOM元素
 * @param attrName 属性名
 * @return 返回根据属性名查找到的CSS属性值
 */
function css(element, attrName) {
	/*if (window.getComputedStyle) // 支持使用 getComputedStyle()  方法
		return getComputedStyle(element)[attrName];
	// IE9之前不支持使用 getComputedStyle() 方法，则使用 currentStyle 属性
	return element.currentStyle[attrName];*/
	
	return window.getComputedStyle
				? getComputedStyle(element)[attrName]
				: element.currentStyle[attrName];
}

/**
 * 注册事件监听，解决兼容问题
 * @param element 待注册事件监听的DOM元素
 * @param type 事件类型字符串
 * @param callback 事件处理程序（函数）
 */
function on(element, type, callback) {
	if (element.addEventListener) { // 支持使用 addEventListener
		if (type.indexOf("on") === 0)  // 事件类型字符串以"on"开头
			type = type.slice(2);
		element.addEventListener(type, callback);
	} else { // 不支持使用 addEventListener，使用 attachEvent()
		if (type.indexOf("on") !== 0) // 没有以 "on" 开头
			type = "on" + type;
		element.attachEvent(type, callback);
	}
}

/**
 * 保存、查询cookie
 * @param key cookie名
 * @param value cookie值，如果该参数未传递，则函数表示查询cookie
 * @param options 可配置参数，如：{expires: 3, path:"/", domain:"", secure:true} 
 */
function cookie(key, value, options) {
	// writing 书写
	if (typeof value !== "undefined") { // 有传递value，则保存 cookie
		options = options || {};
		// 构建保存cookie的字符串，将 key 与 value 都编码
		var cookie = encodeURIComponent(key) + "=" + encodeURIComponent(value);
		// 判断是否有失效时间设置
		if (options.expires) {
			var date = new Date();
			date.setUTCDate(date.getUTCDate() + options.expires);
			cookie += ";expires=" + date.toUTCString();
		}
		// 路径
		if (options.path)
			cookie += ";path=" + options.path;
		// 域
		if (options.domain)
			cookie += ";domain=" + options.domain;
		// 安全链接
		if (options.secure)
			cookie += ";secure";

		// 保存
		return document.cookie = cookie;
	}

	// reading 读取
	// 将域下所有 cookie 的 "key=value" 放到数组中
	var cookies = document.cookie.split("; ");
	// 遍历所有 cookie
	for (var i = 0, len = cookies.length; i < len; i++) {
		// 使用 = 将当前遍历到的 "key=value" 分开
		var parts = cookies[i].split("=");
		// cookie名
		var name = decodeURIComponent(parts.shift());
		// cookie值
		var value =decodeURIComponent(parts.join("="));

		// 判断当前cookie名是否是待查找的 cookie名称
		if (name === key)
			return value;
	}
	// 不能查找到，则返回 undefined
	return undefined;
}

/**
 * 删除 cookie
 * @param key cookie名
 * @param options 配置选项，通常配置 path
 */
function removeCookie(key, options) {
	options = options || {};
	options.expires = -1;
	cookie(key, "", options);
}

